//
//  MCRNBundleHelper.m
//  MeicaiStore
//
//  Created by meicai on 2017/12/20.
//  Copyright © 2017年 Beijing Yunshan Information Technology Co., Ltd. All rights reserved.

#import "MCRNBundleHelper.h"
#import "AFHTTPSessionManager.h"
#import <SSZipArchive/SSZipArchive.h>
#import <MCFoundation/MCFoundation.h>

//amp更新接口文档
//https://wiki.sprucetec.com/pages/viewpage.action?pageId=11404390
static NSString * const kAmpUpgradeURL = @"https://ampapi.yunshanmeicai.com/ampapi/upgrade/upgrade";
static NSString * const kHotfixInfoKey = @"kHotfixInfoKey";
static NSInteger kHotfixStartNumber = 1; // 热更新版本号必须从1开始，如果传0，amp不进行热更新

@implementation MCRNBundleHelper

+ (instancetype)shared {
    static dispatch_once_t onceToken;
    static MCRNBundleHelper *helper = nil;
    dispatch_once(&onceToken, ^{
        helper = [MCRNBundleHelper new];
    });
    return helper;
}


- (instancetype)init
{
    self = [super init];
    if (self) {
        self.jsBundleFileName = @"index.ios.jsbundle";
        self.environment = @"production";
    }
    return self;
}

- (NSURL *)getBundlePath {
    //判断JSBundle是否存在
    NSURL *bundleDirectory = [self  currentHotfixDirectory];
    if (bundleDirectory) {
        NSURL *jsBundleURL = [bundleDirectory URLByAppendingPathComponent:self.jsBundleFileName];
        BOOL jsExist = [[NSFileManager defaultManager] fileExistsAtPath:jsBundleURL.path];
        if (jsExist && [self currentHotfixBuildNumber] > kHotfixStartNumber) {
            return jsBundleURL;
        }
    }
    NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
    if (self.hotfixDirectory.length > 0) {
        bundleURL = [bundleURL URLByAppendingPathComponent:self.hotfixDirectory];
    }
    return [bundleURL URLByAppendingPathComponent:self.jsBundleFileName];

}

- (void)upgrade:(UpgradeType)type
       ampToken:(NSString *)token
         extra:(NSDictionary *)extra
     completion:(void(^)(id responseObject,NSURL *hotfixFileURL, NSError *error))completionHandler {
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"token"] = token;
    params[@"build_id"] = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
    params[@"version_name"] = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    params[@"hotfix_build_id"] = @([self currentHotfixBuildNumber]);
    params[@"device_id"] = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    params[@"upgrade_type"] = @(type);
    params[@"build_env"] = self.environment;
    if ([extra isKindOfClass:[NSDictionary class]]) {
        [params addEntriesFromDictionary:extra];
    }
    __weak typeof(self) weak_self = self;
    [manager POST:kAmpUpgradeURL parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *hotfixData = responseObject[@"data"][@"hotfix"];
        if (type == UpgradeTypeAll || type == UpgradeTypeHotfix){
            if (hotfixData.allKeys.count > 0) {
                [weak_self downloadHotfixZip:hotfixData[@"url"]
                                         md5:hotfixData[@"hotfix_md5"]
                                     version:hotfixData[@"hotfix_build_id"]
                                  completion:^(NSURL *filePath, NSError *error) {
                                      if (completionHandler) completionHandler(responseObject, filePath, error);
                                  }];
            } else {
                if (completionHandler) completionHandler(responseObject, nil, nil);
            }
        } else {
            if (completionHandler) completionHandler(responseObject, nil, nil);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (completionHandler) completionHandler(nil, nil, error);
    }];
}

- (void)downloadHotfixZip:(NSString *)url
                      md5:(NSString *)md5
                  version:(NSString *)version
               completion:(void(^)(NSURL *filePath, NSError *error))completionHandler {
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    NSURL *URL = [NSURL URLWithString:url];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        return [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[response suggestedFilename]]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        if (error) {
            if (completionHandler) completionHandler(filePath, error);
        } else {
            if ([[[NSData dataWithContentsOfFile:filePath.path] mcMD5String] isEqual:md5]) {
                NSError *unzipError = nil;
                [SSZipArchive unzipFileAtPath:filePath.path toDestination:[self generateHotfixDirectory].path overwrite:YES password:nil error:&unzipError];
                if (unzipError) {
                    if (completionHandler) completionHandler(nil, unzipError);
                } else {
                    [self setHotfixBuildNumber:[version integerValue]];
                    [[NSFileManager defaultManager] removeItemAtURL:filePath error:nil];
                    if (completionHandler) completionHandler([self getBundlePath], nil);
                }
            } else {
                if (completionHandler) completionHandler(nil, [NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"文件md5值不匹配"}]);
            }
        }
    }];
    [downloadTask resume];
}


- (void)setHotfixBuildNumber:(NSInteger)number {
    NSString *buildVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
    NSDictionary *hotfixInfo = @{
                                 @"buildVersion":buildVersion,
                                 @"hotfixVersion":@(number),
                                 @"environment":self.environment ?: @""
                                 };
    [[NSUserDefaults standardUserDefaults] setObject:hotfixInfo forKey:kHotfixInfoKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (NSInteger)currentHotfixBuildNumber {
    NSDictionary *hotfixInfo = [[NSUserDefaults standardUserDefaults] objectForKey:kHotfixInfoKey];
    if (hotfixInfo) {
        NSString *buildVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
        if ([buildVersion isEqual:hotfixInfo[@"buildVersion"]]
            && [self.environment isEqual:hotfixInfo[@"environment"]]) {
            return [hotfixInfo[@"hotfixVersion"] integerValue];
        }
    }
    return kHotfixStartNumber;
}

- (NSURL *)currentHotfixDirectory {
    NSURL *fileURL = [self generateHotfixDirectory];
    if ([[NSFileManager defaultManager] fileExistsAtPath:fileURL.path]) {
        return fileURL;
    }
    return nil;
}


- (NSURL *)generateHotfixDirectory {
    NSURL *fileURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    if ([self hotfixDirectory].length > 0) {
        fileURL = [fileURL URLByAppendingPathComponent:self.hotfixDirectory isDirectory:YES];
    }
    return fileURL;
}


@end
